﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using VersionComparer.UI;
using System.Threading;
using System.Drawing;
using System.Xml.Serialization;
using VersionComparer.Base;
using VersionComparer.DataModel.Xml;
using VersionComparer.Comparer;

namespace VersionComparer.Configuration
{

    [XmlInclude (typeof (XmlSettings))]
    [ConfigurationName("settings")]
    public class Settings : SettingsBase
    {
        #region statics
        static Settings settings = GetSettings < Settings>();

        public static Settings Current
        {
            get
            {
                return settings;
            }
        }
        
        #endregion statics


        #region constants
        const string FastMillisecondsDislayName = "Max time before switching to fast";
        const string AlgorithmDisplayName = "Comparison level";
        const string LoadfileTimeoutDisplayName = "File load timeout";
        const string MaxRichTextSizeDisplayName = "Max detail size";
        const string MaxErrorCountDisplayName = "Max error count";
        const string ToggleSidesDisplayName = "Toggle sides";
        const string AskBeforeSavingDisplayName = "Ask before saving";
        const string ShowAllDisplayName = "Show all matches";
        const string OKColorDisplayName = "OK Color";
        const string ErrorColorDisplayName = "No match color";
        const string ChangesColorDisplayName = "Mattch with differences color";
        const string NeutralColorDisplayName = "Neutral color";
        const string DefaultColorDisplayName = "Values color";
        const string IgnorableErrorBackColorDisplayName = "Ignorable differences back color";
        const string IgnorableErrorColorDisplayName = "Ignorable difference color";
        const string AppliedRuleDisplayName = "Rule color";

        const string UnmatchedBackColorDisplayName = "No match back color";
        const string DifferentBackColorDisplayName = "Different back color";
        const string UnexistantBackColorDisplayName = "Unexistant back color";
        const string UnmatchedDimPercentageDisplayName = "Unmatched dim percentage";
        const string OutOfOrderBackColorDisplayName = "Out of order back color";

        const string FastMillisecondsDescription = "Time in milliseconds of comparison when Auto is switched to Fast";
        const string AlgorithmDescription = "Defines the level of comparison. Auto starts as thorough and switches to fast in case the execution takes too long";
        const string LoadfileTimeoutDescription= "Milliseconds timeout to load a file";
        const string MaxRichTextSizeDescription = "Max text length that may be displayed in details windows";
        const string ToggleSidesDescription = "Toggles treeview sides";
        const string MaxErrorCountDescription = "Maximum number of errors for each item";
        const string AskBeforeSavingDescription = "If true a message box is shown before updating an item";
        const string ShowAllDescription = "If true all items are shown - including the ones that are correctly matched";
        const string OKColorDescription = "Color for items with no differences";
        const string AppliedRuleDescription = "Color for items with rules applied";
        const string ErrorColorDescription = "Color for items that do not exist in other file";
        const string ChangesColorDescription = "Color for items that have differences relative to other file";
        const string NeutralColorDescription = "Color for items that have no differences, but are ancestors of nodes with differences";
        const string DefaultColorDescription = "Color used for showing values";
        const string IgnorableErrorBackColorDescription = "Color used for items that have subitems with ignorable differences";
        const string IgnorableErrorColorDescription = "Color used for items that have ignorable differences";
        const string UnmatchedDimPercentageDescription= "Percentage of dim to be applied in unmatched items";


        const string UnmatchedBackColorDescription = "Back color used for items that are unmatched";
        const string UnexistantBackColorDescription = "Back color used for items that do not exist";
        const string DifferentBackColorDescription = "Back color used for items that are different";
        const string OutOfOrderBackColorDescription = "Back color used for items that are out of order";
        

        const string MRUMaxSizeDisplayName = "MRU max size";
        const string MRUMaxSizeDescription = "Maximum number of items shown on the files dropdown";

        const string AllowReorderingDisplayName = "Allow different order";
        const string AllowReorderingDescription = "If true nodes in different orders are not considered errors";

        const string IgnoreCaseDisplayName = "Case sensitiveness";
        const string IgnoreCaseDescription = 
@"Ignore - differences in case are marked as ignorable 
Discard - differences in case are not shown
Show - differences in case are treated as normal errors";

        const bool DefaultAllowReordering = true;
        const bool DefaultToggleSides = false;
        const float DefaultUnmatchedDimPercentage = 0.20f;
        const int DefaultMaxErrorCount = 100;
        const int DefaultMRUMaxSize = 50;
        const int DefaultMaxRichTextSize = 100000;
        const int DefaultLoadfileTimeout = 30000;
        const int DefaultFastMilliseconds = 10000;
        const ComparisonAlgorithm DefaultAlgorithm = ComparisonAlgorithm.Auto;
        const CaseDifferences DefaultIgnoreCase = CaseDifferences.Ignore;
        const bool DefaultShowAll = false;
        const bool DefaultAskBeforeSaving = true;
        #endregion constants

        #region constructors
        public Settings():base()
        {
            UnmatchedDimPercentage = DefaultUnmatchedDimPercentage;
            Algorithm = DefaultAlgorithm;
            FastMilliseconds = DefaultFastMilliseconds;
            LoadfileTimeout = DefaultLoadfileTimeout;
            MaxRichTextSize = DefaultMaxRichTextSize;
            ToggleSides = DefaultToggleSides;
            MaxErrorCount = DefaultMaxErrorCount;
            AskBeforeSaving = DefaultAskBeforeSaving;
            ShowAll = DefaultShowAll;
            OKColor = Color.Green;
            OutOfOrderBackColor = Color.LemonChiffon;
            UnmatchedBackColor = Color.FromArgb(240, 255, 240);
            UnexistantBackColor = Color.FromArgb(255, 192, 192);
            DifferentBackColor = Color.FromArgb(255, 255, 192);
            AppliedRuleColor = Color.FromArgb (202,236,250);
            
            ErrorColor = Color.Red;
            ChangeColor = Color.Blue;
            NeutralColor = Color.Gray;
            DefaultColor = Color.Black;
            IgnorableErrorColor = Color.DarkOrange;
            IgnorableErrorBackColor = Color.FromArgb ( 0xe0, 0xe0, 0xE0);
            AllowReordering = DefaultAllowReordering;
            MRUMaxSize = DefaultMRUMaxSize;
            
            IgnoreCase = DefaultIgnoreCase;
        }
        #endregion constructors

        #region properties


        public override string Name
        {
            get 
            {
                return Resources.Resources.GenericSettingsName;
            }
        }




        [DisplayName(FastMillisecondsDislayName)]
        [Description(FastMillisecondsDescription)]
        [DefaultValue(DefaultFastMilliseconds)]
        [Category(CATEGORY_ALGORITHM)]
        public int FastMilliseconds
        {
            get
            {
                return fastMilliseconds;
            }
            set
            {
                if (fastMilliseconds !=value)
                {
                    fastMilliseconds = value;
                    SomethingChanged = true;
                }
            }
        }

        int fastMilliseconds;
            
        [DisplayName(AlgorithmDisplayName)]
        [Description(AlgorithmDescription)]
        [DefaultValue(DefaultAlgorithm)]
        [Category(CATEGORY_ALGORITHM)]
        public ComparisonAlgorithm Algorithm
        {
            get
            {
                return algorithm;
            }
            set
            {
                if (value != algorithm)
                {
                    algorithm = value;
                    SomethingChanged = true;
                }
            }
        }
        ComparisonAlgorithm algorithm;

        [DisplayName(LoadfileTimeoutDisplayName)]
        [Description(LoadfileTimeoutDescription)]
        [DefaultValue(DefaultLoadfileTimeout)]
        [Category(CATEGORY_ALGORITHM)]
        public int LoadfileTimeout
        {
            get;
            set;
        }

        [DisplayName(MaxRichTextSizeDisplayName)]
        [Description(MaxRichTextSizeDescription)]
        [DefaultValue(DefaultMaxRichTextSize)]
        [Category(CATEGORY_ALGORITHM)]
        public int MaxRichTextSize
        {
            get;
            set;
        }

        [DisplayName(MaxErrorCountDisplayName)]
        [Description(MaxErrorCountDescription)]
        [DefaultValue(DefaultMaxErrorCount)]
        [Category(CATEGORY_ALGORITHM)]
        public int MaxErrorCount
        {
            get;
            set;
        }

        [DisplayName(ToggleSidesDisplayName)]
        [Description(ToggleSidesDescription)]
        [DefaultValue(DefaultToggleSides)]
        [Category(CATEGORY_GENERAL)]
        public bool ToggleSides
        {
            get;
            set;
        }

        [DisplayName(AllowReorderingDisplayName)]
        [Description(AllowReorderingDescription)]
        [DefaultValue(DefaultAllowReordering)]
        [Category (CATEGORY_ALGORITHM)]
        public bool AllowReordering
        {
            get
            {
                return allowReordering;
            }
            set
            {
                if (allowReordering != value)
                {
                    SomethingChanged = true;
                    allowReordering = value;
                }
            }
        }
        bool allowReordering;

        [Browsable (false)]
        public int SerializableOKColor
        {
            get
            {
                return OKColor.ToArgb();
            }
            set
            {
                OKColor = Color.FromArgb(value);
            }
        }

        [Browsable(false)]
        public int SerializableUnexistantBackColor
        {
            get
            {
                return UnexistantBackColor.ToArgb();
            }
            set
            {
                UnexistantBackColor = Color.FromArgb(value);
            }
        }

        
        [Browsable(false)]
        public int SerializableUnmatchedBackColor
        {
            get
            {
                return UnmatchedBackColor.ToArgb();
            }
            set
            {
                UnmatchedBackColor = Color.FromArgb(value);
            }
        }

        [Browsable(false)]
        public int SerializableOutOfOrderBackColor
        {
            get
            {
                return OutOfOrderBackColor.ToArgb();
            }
            set
            {
                OutOfOrderBackColor = Color.FromArgb(value);
            }
        }

        [Browsable(false)]
        public int SerializableDifferentBackColor
        {
            get
            {
                return DifferentBackColor.ToArgb();
            }
            set
            {
                DifferentBackColor = Color.FromArgb(value);
            }
        }
         [Browsable (false)]
        public int SerializableAppliedRule
        {
            get
            {
                return AppliedRuleColor.ToArgb();
            }
            set
            {
                AppliedRuleColor = Color.FromArgb(value);
            }
        }
        
        [Browsable(false)]
        public int SerializableErrorColor
        {
            get
            {
                return ErrorColor.ToArgb();
            }
            set
            {
                ErrorColor = Color.FromArgb(value);
            }
        }
        [Browsable(false)]
        public int SerializableChangeColor
        {
            get
            {
                return ChangeColor.ToArgb();
            }
            set
            {
                ChangeColor = Color.FromArgb(value);
            }
        }
        [Browsable(false)]
        public int SerializableNeutralColor
        {
            get
            {
                return NeutralColor.ToArgb();
            }
            set
            {
                NeutralColor = Color.FromArgb(value);
            }
        }
        
        [Browsable(false)]
        public int SerializableIgnorableErrorBackColor
        {
            get
            {
                return IgnorableErrorBackColor.ToArgb();
            }
            set
            {
                IgnorableErrorBackColor = Color.FromArgb(value);
            }
        }

        [Browsable(false)]
        public int SerializableIgnorableErrorColor
        {
            get
            {
                return IgnorableErrorColor.ToArgb();
            }
            set
            {
                IgnorableErrorColor = Color.FromArgb(value);
            }
        }

        [Browsable(false)]
        public int SerializableDefaultColor
        {
            get
            {
                return DefaultColor.ToArgb();
            }
            set
            {
                DefaultColor = Color.FromArgb(value);
            }
        }


        [DisplayName(AppliedRuleDisplayName)]
        [Description(AppliedRuleDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color AppliedRuleColor
        {
            get;
            set;
        }
        [DisplayName(OKColorDisplayName)]
        [Description(OKColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color OKColor
        {
            get;
            set;
        }

        [DisplayName(UnexistantBackColorDisplayName )]
        [Description(UnexistantBackColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color UnexistantBackColor
        {
            get;
            set;
        }

        [DisplayName(OutOfOrderBackColorDisplayName)]
        [Description(OutOfOrderBackColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color OutOfOrderBackColor
        {
            get;
            set;
        }


        
        [DisplayName(DifferentBackColorDisplayName)]
        [Description(DifferentBackColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color DifferentBackColor
        {
            get;
            set;
        }

        [DisplayName(UnmatchedBackColorDisplayName)]
        [Description(UnmatchedBackColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color UnmatchedBackColor
        {
            get;
            set;
        }


        [DisplayName(ErrorColorDisplayName)]
        [Description(ErrorColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color ErrorColor
        {
            get;
            set;
        }
        [DisplayName(ChangesColorDescription)]
        [Description(ChangesColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color ChangeColor
        {
            get;
            set;
        }


        [DisplayName(NeutralColorDisplayName)]
        [Description(NeutralColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color NeutralColor
        {
            get;
            set;
        }



        [DisplayName(IgnorableErrorColorDisplayName)]
        [Description(IgnorableErrorColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color IgnorableErrorColor
        {
            get;
            set;
        }

        [DisplayName(IgnorableErrorBackColorDisplayName)]
        [Description(IgnorableErrorBackColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color IgnorableErrorBackColor
        {
            get;
            set;
        }

        [DisplayName(DefaultColorDisplayName)]
        [Description(DefaultColorDescription)]
        [Category(CATEGORY_COLORS)]
        [System.Xml.Serialization.XmlIgnore]
        public Color DefaultColor
        {
            get;
            set;
        }

        [DisplayName(MRUMaxSizeDisplayName)]
        [Description(MRUMaxSizeDescription)]
        [DefaultValue(DefaultMRUMaxSize)]
        [Category(CATEGORY_ALGORITHM)]
        public int MRUMaxSize
        {
            get;
            set;
        }

        [DisplayName(UnmatchedDimPercentageDisplayName)]
        [Description(UnmatchedDimPercentageDescription)]
        [DefaultValue(DefaultUnmatchedDimPercentage)]
        [Category(CATEGORY_COLORS)]
        public float UnmatchedDimPercentage
        {
            get;
            set;
        }
        
        [DisplayName(IgnoreCaseDisplayName)]
        [Description(IgnoreCaseDescription)]
        [DefaultValue(DefaultIgnoreCase)]
        [Category(CATEGORY_ALGORITHM)]
        public CaseDifferences IgnoreCase
        {
            get
            {
                return ignoreCase;
            }
            set
            {
                if (ignoreCase != value)
                {
                    SomethingChanged = true;
                    ignoreCase = value;
                }
            }
        }
        CaseDifferences ignoreCase;

        [DisplayName(ShowAllDisplayName)]
        [Description(ShowAllDescription)]
        [Category(CATEGORY_ALGORITHM)]
        public bool ShowAll
        {
            get
            {
                return showAll;
            }
            set
            {
                if (showAll != value)
                {
                    SomethingChanged = true;
                    showAll = value;
                }
            }
        }
        bool showAll;

        [DisplayName(AskBeforeSavingDisplayName)]
        [Description(AskBeforeSavingDescription)]
        [Category(CATEGORY_GENERAL)]
        public bool AskBeforeSaving
        {
            get;
            set;
        }


        #endregion properties

        /*
        public bool ShowDialog()
        {
            ControlContainerForm<SettingsControl> form = new ControlContainerForm<SettingsControl>();
            form.Control.Settings = this;
            if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Save();
                return true;
            }
            else
            {
                Interlocked.Exchange(ref settings, LoadSettings());
                return false;
            }

        }
        */
    }
}
